home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / PRIEST.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  15KB  |  578 lines

  1. /*    SCCS Id: @(#)priest.c    3.0    89/06/26
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* Copyright (c) Izchak Miller, Steve Linhart, 1989. */
  4. /* NetHack may be freely redistributed.  See license for details. */
  5.  
  6. #define MONATTK_H    /* comment line for pre-compiled headers */
  7. /* block some unused #defines to avoid overloading some cpp's */
  8. #include "hack.h"
  9. #include "mfndpos.h"
  10. #include "eshk.h"
  11. #include "epri.h"
  12.  
  13. #ifdef OVLB
  14.  
  15. #if defined(ALTARS) && defined(THEOLOGY)
  16. static boolean FDECL(histemple_at,(struct monst *,int,int));
  17. static int FDECL(t_alignment,(struct mkroom *));
  18. static boolean FDECL(is_shrined,(struct mkroom *));
  19. static boolean FDECL(t_coaligned,(struct mkroom *));
  20. struct monst *FDECL(findpriest,(struct mkroom *));
  21. static boolean FDECL(p_inhistemple,(struct mkroom *));
  22. #endif
  23.  
  24. /* used for the insides of shk_move and pri_move */
  25. int
  26. move_special(mtmp,monroom,appr,uondoor,avoid,omx,omy,gx,gy)
  27. register struct monst *mtmp;
  28. schar monroom,appr;
  29. boolean uondoor,avoid;
  30. register xchar omx,omy,gx,gy;
  31. {
  32.     register xchar nx,ny,nix,niy;
  33.     register schar i;
  34.     schar chcnt,cnt;
  35.     coord poss[9];
  36.     long info[9];
  37.     long allowflags;
  38.     struct obj *ib = 0;
  39.  
  40.     if(omx == gx && omy == gy)
  41.         return(0);
  42.     if(mtmp->mconf) {
  43.         avoid = FALSE;
  44.         appr = 0;
  45.     }
  46.  
  47.     nix = omx;
  48.     niy = omy;
  49.     if (mtmp->isshk) allowflags = ALLOW_SSM;
  50.     else allowflags = ALLOW_SSM | ALLOW_SANCT;
  51.     if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
  52.     if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
  53.     if (tunnels(mtmp->data) &&
  54.             (!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE)))
  55.         allowflags |= ALLOW_DIG;
  56.     if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
  57.         allowflags |= OPENDOOR;
  58.         if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
  59.     }
  60.     if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
  61.     cnt = mfndpos(mtmp, poss, info, allowflags);
  62.     if (allowflags & ALLOW_DIG) if(!mdig_tunnel(mtmp)) return(-2);
  63.  
  64.     if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
  65.         for(i=0; i<cnt; i++)
  66.             if(!(info[i] & NOTONL)) goto pick_move;
  67.         avoid = FALSE;
  68.     }
  69.  
  70. #define    GDIST(x,y)    (dist2(x,y,gx,gy))
  71. pick_move:
  72.     chcnt = 0;
  73.     for(i=0; i<cnt; i++) {
  74.         nx = poss[i].x;
  75.         ny = poss[i].y;
  76.         if(levl[nx][ny].typ == ROOM ||
  77. #if defined(ALTARS) && defined(THEOLOGY)
  78.             (mtmp->ispriest &&
  79.                 levl[nx][ny].typ == ALTAR) ||
  80. #endif
  81.             (mtmp->isshk &&
  82.                 (monroom != ESHK(mtmp)->shoproom
  83.                 || ESHK(mtmp)->following))) {
  84.             if(avoid && (info[i] & NOTONL))
  85.             continue;
  86.             if((!appr && !rn2(++chcnt)) ||
  87.             (appr && GDIST(nx,ny) < GDIST(nix,niy))) {
  88.                 nix = nx;
  89.                 niy = ny;
  90.             }
  91.         }
  92.     }
  93. #if defined(ALTARS) && defined(THEOLOGY)
  94.     if(mtmp->ispriest && avoid &&
  95.             nix == omx && niy == omy && online(omx,omy)) {
  96.         /* might as well move closer as long it's going to stay
  97.          * lined up */
  98.         avoid = FALSE;
  99.         goto pick_move;
  100.     }
  101. #endif
  102.  
  103.     if(nix != omx || niy != omy) {
  104.         remove_monster(omx, omy);
  105.         place_monster(mtmp, nix, niy);
  106.         pmon(mtmp);
  107.         if(ib) {
  108.             if (cansee(mtmp->mx,mtmp->my))
  109.                 pline("%s picks up %s.", Monnam(mtmp),
  110.                 distant_name(ib,doname));
  111.             freeobj(ib);
  112.             mpickobj(mtmp, ib);
  113.         }
  114.         return(1);
  115.     }
  116.     return(0);
  117. }
  118.  
  119. #endif /* OVLB */
  120.  
  121. #if defined(ALTARS) && defined(THEOLOGY)
  122.  
  123. #ifdef OVL0
  124.  
  125. struct mkroom *
  126. in_temple(x, y)
  127. register int x, y;
  128. {
  129.     register int roomno = inroom(x, y);
  130.  
  131.     if (roomno < 0 || rooms[roomno].rtype != TEMPLE)
  132.         return((struct mkroom *)0);
  133.     return(&rooms[roomno]);
  134. }
  135.  
  136. #endif /* OVL0 */
  137. #ifdef OVLB
  138.  
  139. static boolean
  140. histemple_at(priest, x, y)
  141. register struct monst *priest;
  142. register int x, y;
  143. {
  144.     return(EPRI(priest)->shroom == inroom(x, y) && 
  145.            EPRI(priest)->shrlevel == dlevel);
  146. }
  147.  
  148. /*
  149.  * pri_move: return 1: he moved  0: he didn't  -1: let m_move do it  -2: died
  150.  */
  151. int
  152. pri_move(priest)
  153. register struct monst *priest;
  154. {
  155.     register xchar gx,gy,omx,omy;
  156.     schar temple;
  157.     boolean avoid = TRUE;
  158.  
  159.     omx = priest->mx;
  160.     omy = priest->my;
  161.  
  162.     if(!histemple_at(priest, omx, omy)) return(-1);
  163.  
  164.     temple = EPRI(priest)->shroom;
  165.     
  166.     gx = EPRI(priest)->shrpos.x;
  167.     gy = EPRI(priest)->shrpos.y;
  168.  
  169.     gx += rn1(3,-1);    /* mill around the altar */
  170.     gy += rn1(3,-1);
  171.  
  172.     if(!priest->mpeaceful) {
  173.         if(monnear(priest, u.ux, u.uy)) {
  174.             if(Displaced)
  175.                 Your("displaced image doesn't fool %s!",
  176.                     mon_nam(priest));
  177.             (void) mattacku(priest);
  178.             return(0);
  179.         } else if(temple == inroom(u.ux,u.uy)) {
  180.             /* don't chase player outside temple */
  181.             long saveBlind = Blinded;
  182.             struct obj *saveUblindf = ublindf;
  183.             Blinded = 0;
  184.             ublindf = (struct obj *)0;
  185.             if(priest->mcansee && !Invis && cansee(omx,omy)) {
  186.                 gx = u.ux;
  187.                 gy = u.uy;
  188.             }
  189.             Blinded = saveBlind;
  190.             ublindf = saveUblindf;
  191.             avoid = FALSE;
  192.         }
  193.     } else if(Invis) avoid = FALSE;
  194.     
  195.     return(move_special(priest,temple,TRUE,FALSE,avoid,omx,omy,gx,gy));
  196. }
  197.  
  198. /* exclusively for mktemple() */
  199. void
  200. priestini(lvl, sx, sy, align)
  201. register int lvl, sx, sy, align;
  202. {
  203.     register struct monst *priest;
  204.     register struct obj *otmp = (struct obj *)0;
  205. #ifdef SPELLS
  206.     register int cnt;
  207. #endif
  208.     if(MON_AT(sx+1, sy)) rloc(m_at(sx+1, sy)); /* insurance */
  209.  
  210.     if(priest = makemon(&mons[!rn2(2) ? PM_TEMPLE_PRIEST : 
  211.             PM_TEMPLE_PRIESTESS], sx+1, sy)) {
  212.         EPRI(priest)->shroom = inroom(sx, sy);
  213.         EPRI(priest)->shralign = align;
  214.         EPRI(priest)->shrpos.x = sx;
  215.         EPRI(priest)->shrpos.y = sy;
  216.         EPRI(priest)->shrlevel = lvl;
  217.         EPRI(priest)->ismale = 
  218.                 (priest->data == &mons[PM_TEMPLE_PRIEST]);
  219.         Strcpy(EPRI(priest)->deitynam, a_gname_at(sx, sy));
  220.         priest->mtrapseen = ~0;    /* traps are known */
  221.         priest->mpeaceful = 1;
  222.         priest->ispriest = 1;
  223.         priest->msleep = 0;
  224.  
  225.         /* now his/her goodies... */
  226.         (void) mongets(priest, CHAIN_MAIL);
  227.         (void) mongets(priest, SMALL_SHIELD);
  228.  
  229.         /* Do NOT put the rest in m_initinv.    */
  230.         /* Priests created elsewhere than in a  */
  231.         /* temple should not carry these items, */
  232.         /* except for the mace.            */
  233. #ifdef SPELLS
  234.         cnt = rn1(2,3);
  235.         while(cnt) {
  236.             otmp = mkobj(SPBOOK_SYM, FALSE);
  237.             if(otmp) mpickobj(priest, otmp);
  238.             cnt--;
  239.         }
  240. #endif
  241.         if(p_coaligned(priest))
  242.             (void) mongets(priest, rn2(2) ? CLOAK_OF_PROTECTION
  243.                           : CLOAK_OF_MAGIC_RESISTANCE);
  244.         else {
  245.             if(!rn2(5)) 
  246.             otmp = mksobj(CLOAK_OF_MAGIC_RESISTANCE, FALSE); 
  247.             else otmp = mksobj(CLOAK_OF_PROTECTION, FALSE); 
  248.             if(otmp) {
  249.             if(!rn2(2)) curse(otmp);
  250.             mpickobj(priest, otmp);
  251.             }
  252.         }
  253.  
  254.         otmp = mksobj(MACE, FALSE);
  255.         if(otmp) {
  256.             otmp->spe = rnd(3);
  257.             if(!rn2(2)) curse(otmp);
  258.             mpickobj(priest, otmp);
  259.         }
  260.     }
  261. }
  262.  
  263. char *
  264. priestname(priest)
  265. register struct monst *priest;
  266. {
  267.     static char NEARDATA pname[PL_NSIZ];
  268.  
  269.     Strcpy(pname, "the ");
  270.     if(priest->minvis) Strcat(pname, "invisible ");
  271.     if(priest->data != &mons[PM_TEMPLE_PRIEST] &&
  272.             priest->data != &mons[PM_TEMPLE_PRIESTESS]) {
  273.         Strcat(pname, priest->data->mname);
  274.         Strcat(pname, " ");
  275.     }
  276.     if(EPRI(priest)->ismale)
  277.         Strcat(pname, "priest of ");
  278.     else     Strcat(pname, "priestess of ");
  279.     Strcat(pname, EPRI(priest)->deitynam);
  280.     return(pname);
  281. }
  282.  
  283. boolean
  284. p_coaligned(priest)
  285. struct monst *priest;
  286. {
  287.     return(!strcmp(u_gname(), EPRI(priest)->deitynam));
  288. }
  289.  
  290. static int
  291. t_alignment(troom)
  292. struct mkroom *troom;
  293. {
  294.     int x, y;
  295.  
  296.     shrine_pos(&x,&y,troom);
  297.  
  298.     if(IS_ALTAR(levl[x][y].typ) && (levl[x][y].altarmask & A_SHRINE) != 0)
  299.         return(levl[x][y].altarmask & ~A_SHRINE); 
  300.     return(-2); /* arbitrary non-alignment type value */
  301. }
  302.  
  303. static boolean
  304. is_shrined(troom)
  305. struct mkroom *troom;
  306. {
  307.     int x, y;
  308.  
  309.     shrine_pos(&x,&y,troom);
  310.  
  311.     if(IS_ALTAR(levl[x][y].typ) && (levl[x][y].altarmask & A_SHRINE) != 0)
  312.         return(TRUE);
  313.     return(FALSE);
  314. }
  315.  
  316. static boolean
  317. t_coaligned(troom)
  318. struct mkroom *troom;
  319. {
  320.     return(t_alignment(troom) == u.ualigntyp + 1);
  321. }
  322.  
  323. struct monst *
  324. findpriest(troom)
  325. struct mkroom *troom;
  326. {
  327.     register struct monst *mtmp;
  328.     extern struct monst *fdmon; /* from mon.c */
  329.  
  330.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  331.         if(mtmp->ispriest && histemple_at(mtmp,mtmp->mx,mtmp->my)
  332.             && &rooms[EPRI(mtmp)->shroom] == troom)
  333.         return(mtmp);
  334.     for(mtmp = fdmon; mtmp; mtmp = mtmp->nmon)
  335.         if(mtmp->ispriest && histemple_at(mtmp,mtmp->mx,mtmp->my)
  336.             && &rooms[EPRI(mtmp)->shroom] == troom)
  337.         return(mtmp);
  338.     return (struct monst *)0;
  339. }
  340.  
  341. static boolean
  342. p_inhistemple(troom)
  343. struct mkroom *troom;
  344. {
  345.     register struct monst *priest;
  346.  
  347.     priest = findpriest(troom);
  348.     if(priest) return(TRUE);
  349.     return(FALSE);
  350. }
  351.  
  352. void
  353. intemple() {
  354.     register struct mkroom *troom;
  355.  
  356.     if(troom = in_temple(u.ux, u.uy)) {
  357.         boolean shrined = is_shrined(troom);
  358.         boolean tended = p_inhistemple(troom);
  359.  
  360.         if(!in_temple(u.ux0, u.uy0)) {
  361.         pline("Pilgrim, you enter a%s place!",
  362.             (!(shrined || tended) ? " desecrated and deserted" :
  363.              !shrined ? " desecrated" :
  364.              !tended ? "n untended sacred" :
  365.               " sacred"));
  366.         if(!t_coaligned(troom) || u.ualign < -5 || !shrined || !tended)
  367.             You("have a%s forbidding feeling...",
  368.                 (!shrined || !tended) ? "" :
  369.                  " strange");
  370.         else You("experience a strange sense of peace.");
  371.         } else if(!(shrined || tended) && !rn2(5)) {
  372.         switch(rn2(3)) {
  373.             case 0: You("have an eerie feeling..."); break;
  374.             case 1: You("feel like you are being watched."); break;
  375.             default: pline("A shiver runs down your spine."); break;
  376.         }
  377.         if(!rn2(5)) {
  378.             struct monst *mtmp;
  379.  
  380.             if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))) return;
  381.             pline("An enormous ghost appears next to you!");
  382.             mtmp->mpeaceful = 0;
  383.             if(flags.verbose)
  384.                 You("are frightened to death, and unable to move.");
  385.             nomul(-3);
  386.             nomovemsg = "You regain your composure.";
  387.         }
  388.         }
  389.     }
  390. }
  391.  
  392. void
  393. priest_talk(priest)
  394. register struct monst *priest;
  395. {
  396.     boolean coaligned = p_coaligned(priest);
  397.     boolean strayed = (u.ualign < 0);
  398.  
  399.     if(priest->mflee) {
  400.         kludge("%s doesn't want anything to do with you!", 
  401.                 Monnam(priest));
  402.         priest->mtame = priest->mpeaceful = 0;
  403.         return;
  404.     }
  405.  
  406.     /* priests don't chat unless peaceful and in their own temple */
  407.     if(!histemple_at(priest,priest->mx,priest->my) || priest->mtame ||
  408.          !priest->mpeaceful || !priest->mcanmove || priest->msleep) {
  409.             if(!priest->mcanmove || priest->msleep) {
  410.             kludge("%s breaks out of his reverie!", Monnam(priest));
  411.                 priest->mfrozen = priest->msleep = 0;
  412.         priest->mcanmove = 1;
  413.         }
  414.         /* The following is now impossible according to monst.c, */
  415.         /* but it should stay just in case we change the latter. */
  416.         if(priest->mtame)
  417.         kludge("%s breaks out of your taming spell!", Monnam(priest));
  418.         priest->mtame = priest->mpeaceful = 0;
  419.         switch(rn2(3)) {
  420.             case 0: 
  421.            verbalize("Thou wouldst have words, eh?  I'll give thee a word or two!"); 
  422.            break;
  423.             case 1: 
  424.            verbalize("Talk?  Here is what I have to say!"); 
  425.            break;
  426.             default: 
  427.            verbalize("Pilgrim, I have lost mine desire to talk.");
  428.            break;
  429.         }
  430.         return;
  431.     }
  432.  
  433.     /* he desecrated the temple and now he wants to chat? */
  434.     if(!is_shrined(&rooms[inroom(priest->mx, priest->my)])
  435.         && priest->mpeaceful) {
  436.         verbalize("Begone!  Thou desecratest this holy place with thy presence.");
  437.         priest->mpeaceful = 0;
  438.         return;
  439.     } 
  440.  
  441.     if(!u.ugold) {
  442.         if(coaligned && !strayed) {
  443.             kludge("%s gives you two bits for an ale.", Monnam(priest));
  444.             u.ugold = 2L;
  445.         if (priest->mgold) priest->mgold -= 2L;
  446.         flags.botl = 1;
  447.         } else
  448.         kludge("%s is not interested.", Monnam(priest));
  449.         return;
  450.     } else {
  451.         long offer;
  452.  
  453.         kludge("%s asks you for a contribution for the temple.",
  454.             Monnam(priest));
  455.         if((offer = bribe(priest)) == 0) {
  456.         verbalize("Thou shalt regret thine action!");
  457.         if(coaligned) u.ualign--;
  458.         } else if(offer < (u.ulevel * 200)) {
  459.         if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
  460.         else {
  461.             verbalize("I thank thee for thy contribution.");
  462.             /*  give player some token  */
  463.         }
  464.         } else if(offer < (u.ulevel * 400)) {
  465.         verbalize("Thou art indeed a pious individual.");
  466.         if(u.ugold < (offer * 2L)) { 
  467.             if(coaligned && u.ualign < -5) u.ualign++;
  468.             verbalize("I bestow upon thee a blessing.");
  469.             Clairvoyant += rn1(500,500);
  470.         }
  471.         } else if(offer < (u.ulevel * 600)) {
  472.         verbalize("Thy devotion has been rewarded.");
  473.         if (!(Protection & INTRINSIC))  {
  474.             Protection |= INTRINSIC;
  475.             if (!u.ublessed)  u.ublessed = rnd(3) + 1;
  476.         } else u.ublessed++;
  477.         } else {
  478.         verbalize("Thy selfless generosity is deeply appreciated.");
  479.         if(u.ugold < (offer * 2L) && coaligned) {
  480.             if(strayed && (moves - u.ucleansed) > 5000L) { 
  481.             u.ualign = 0; /* cleanse him */
  482.             u.ucleansed = moves;
  483.             } else { 
  484.                 u.ualign += 2;
  485.             }
  486.         }
  487.         }
  488.     }
  489. }
  490.  
  491. boolean
  492. u_in_sanctuary(troom) 
  493. register struct mkroom *troom;
  494. {
  495.     register struct mkroom *troom2;
  496.  
  497.     troom2 = in_temple(u.ux, u.uy);
  498.  
  499.     return(troom && troom2 && troom == troom2 && is_shrined(troom2) && 
  500.             t_coaligned(troom2) && u.ualign > -5);
  501. }
  502.  
  503. void
  504. ghod_hitsu()     /* when attacking a priest in his temple */
  505. {
  506.     int x, y, ax, ay;
  507.     struct monst *priest;
  508.     struct mkroom *troom = in_temple(u.ux, u.uy);
  509.  
  510.     if(!troom || !is_shrined(troom)) return;
  511.  
  512.     /* shrine converted by human sacrifice */
  513.     if((priest = findpriest(troom)) && 
  514.         strcmp(EPRI(priest)->deitynam,
  515.         a_gname_at(EPRI(priest)->shrpos.x, EPRI(priest)->shrpos.y))) 
  516.             return;
  517.  
  518.     shrine_pos(&x,&y,troom);
  519.     ax = x;
  520.     ay = y;
  521.  
  522.     if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
  523.         if(IS_DOOR(levl[u.ux][u.uy].typ)) {
  524.         if(u.ux == troom->lx - 1) {
  525.             x = troom->hx;
  526.             y = u.uy;
  527.         } else if(u.ux == troom->hx + 1) {
  528.             x = troom->lx;
  529.             y = u.uy;
  530.         } else if(u.uy == troom->ly - 1) {
  531.             x = u.ux;
  532.             y = troom->hy;
  533.         } else if(u.uy == troom->hy + 1) {
  534.             x = u.ux;
  535.             y = troom->ly;
  536.         }
  537.         } else {
  538.         switch(rn2(4)) {
  539.         case 0:  x = u.ux; y = troom->ly; break;
  540.         case 1:  x = u.ux; y = troom->hy; break;
  541.         case 2:  x = troom->lx; y = u.uy; break;
  542.         default: x = troom->hx; y = u.uy; break;
  543.         }
  544.         }
  545.         if(!linedup(u.ux, u.uy, x, y)) return;
  546.     }
  547.  
  548.     switch(rn2(3)) {
  549.     case 0: 
  550.         pline("%s roars in anger:  \"Thou shalt suffer!\"", 
  551.             a_gname_at(ax, ay));
  552.         break;
  553.     case 1: 
  554.         pline("%s's voice booms:  \"How darest thou harm my servant!\"",
  555.             a_gname_at(ax, ay));
  556.         break;
  557.     default: 
  558.         pline("%s roars:  \"Thou dost profane my shrine!\"",
  559.             a_gname_at(ax, ay));
  560.         break;
  561.     }
  562.  
  563.     buzz(-15, 6, x, y, sgn(tbx), sgn(tby)); /* -15: bolt of lightning */
  564. }
  565.  
  566. void
  567. angry_priest()
  568. {
  569.     register struct monst *priest;
  570.  
  571.     if(!(priest = findpriest(in_temple(u.ux, u.uy)))) return;
  572.     wakeup(priest);
  573. }
  574.  
  575. #endif /* OVLB */
  576. #endif /* ALTARS && THEOLOGY */
  577.  
  578.